#include "marshaling.h"

//SERVER:
void (*function_table[MAX_FUNCTION_NUM+1])(void* parameters, void** ans, int* ans_size); 

void add_query(int function_num, void (*function)(void* parameters, void** ans, int* ans_size)){
	function_table[function_num]=function;
}

int demarshal_query(message_t* msg, void** parameters){
	*parameters = msg->text + sizeof(int);
	return *((int*)msg->text);
}

message_t marshal_answer(void* ans, int ans_size){
	message_t to_send;
	to_send.size= ans_size;
	to_send.text=(char*)ans;
	return to_send;
}

int listen_query(){
	int client;
	message_t message;

	if((client = ipc_msg_recive(CLIENT, &message)) < 0) return -1;
	void* parameters;
	int function_num=demarshal_query(&message, &parameters);

	void* ans;
	int ans_size;
	function_table[function_num](parameters, &ans, &ans_size);
	free(message.text);

	
	message = marshal_answer(ans, ans_size);
	if(ipc_msg_send(client, &message)<0)return -1;
	free(ans);

	return 0;
}



//CLIENT:


message_t marshal_query(int function_num, void* parameters, int parameters_size){
	message_t to_send;

	to_send.size=parameters_size + sizeof(int);
	to_send.text=malloc(to_send.size);//FREE
	char* plaintextp=to_send.text;

	*((int*)plaintextp)=function_num;
	plaintextp+=sizeof(int);

	memcpy(plaintextp,parameters,parameters_size);

	return to_send;
}



int demarshal_answer(message_t* msg, void** ans){
	*ans=msg->text;
	return msg->size;
}


int make_query(int function_num, void* parameters, int parameters_size, void** ans){
	message_t message;

	message=marshal_query(function_num, parameters, parameters_size);
	if(ipc_msg_send(SERVER, &message)<0) return -1;
	free(message.text);
	
	if(ipc_msg_recive(SERVER, &message)!=SERVER) return -1;
	return demarshal_answer(&message, ans);
}
